package me.illtamer.rpc.util;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import lombok.extern.slf4j.Slf4j;
import me.illtamer.rpc.enumeration.RpcError;
import me.illtamer.rpc.exception.RpcException;

import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 管理 Nacos 连接的工具类
 * */
@Slf4j
public class NacosUtil {

    /**
     * Nacos 服务的地址
     * */
    private static final String SERVER_ADDR = "127.0.0.1:8848";
    private static final NamingService SERVICE = getNacosNamingService();
    private static final Set<String> SERVICE_NAMES = new HashSet<>();

    private static InetSocketAddress address;

    private NacosUtil() {}

    /**
     * 连接到 Nacos 创建命名空间
     * */
    public static NamingService getNacosNamingService() {
        try {
            return NamingFactory.createNamingService(SERVER_ADDR);
        } catch (NacosException e) {
            log.error("连接到 Nacos 时有错误发生", e);
            throw new RpcException(RpcError.FAILED_TO_CONNECT_TO_SERVICE_REGISTRY);
        }
    }

    /**
     * 注册服务到 Nacos，创建命名空间
     * */
    public static void registerService(String name, InetSocketAddress address0) throws NacosException {
        SERVICE.registerInstance(name, address0.getHostName(), address0.getPort());
        address = address0;
        SERVICE_NAMES.add(name);
    }

    /**
     * 获取所有提供该服务的服务端地址
     * */
    public static List<Instance> getAllInstance(String name) throws NacosException {
        return SERVICE.getAllInstances(name);
    }

    /**
     * 注销服务
     * */
    public static void clearRegistry() {
        if (!SERVICE_NAMES.isEmpty() && address != null) {
            String host = address.getHostName();
            int port = address.getPort();
            for (String name : SERVICE_NAMES) {
                try {
                    SERVICE.deregisterInstance(name, host, port);
                } catch (NacosException e) {
                    log.error("注销 {} 失败", name, e);
                }
            }
        }
    }

}
